#include <ilcplex/cplex.h>
#include <stdlib.h>
#include <string.h>
#include "network.h"
#include "cplexhead.h"
#include "master_constraints.h"
#include <iostream>
#include <map>
using namespace std;



int cplexhead::getE(){
  return E;
}
int cplexhead::getC(){
  return C;
}
int cplexhead::getN(){
  return N;
}

int cplexhead::mapsize(){
  return variabel.size();
}

int cplexhead::getmapinfo(string key, int pos){
  return variabel[key][pos];
}

map < string, vector<int> > cplexhead::getmap(){
  return variabel;
}

cplexhead::cplexhead(int input_E,int input_C,int input_N){
    //set param
    E = input_E;
    C = input_C;
    N = input_N;
   
    vector<int> endvec (2);
    endvec[0] = 0; endvec[1] = 0; 
    variabel["end"] = endvec;
    
    NUMCOLS = variabel["end"][0];

    last_name ="end"; 
}

void cplexhead::addvar(string name, int length, int active){

  map < string, vector<int> >  myMap = getmap();
  
 vector<int> vec (2);
 vec[0] = myMap[last_name][1]; vec[1]= vec[0] + length*active;  
 variabel[name] = vec;
 
 last_name = name;

 NUMCOLS = vec[1];

}

int cplexhead::getcols(){
  return NUMCOLS;
}

int cplexhead::idx_x(int idx_edge,int com){
  return -1;;
}

void cplexhead::print(){
  cout<<"E:" <<E<<" N: "<<N<<"C: "<<C<<"Numcols: "<<NUMCOLS<<"\n";
} 


CPXENVptr makeEnv(int status){
 CPXENVptr env = CPXopenCPLEX (&status);
  if ( env == NULL ) {
    char errmsg[1024];
    fprintf (stderr, "Could not open CPLEX environment.\n");
    CPXgeterrorstring (env, status, errmsg);
    fprintf (stderr, "%s", errmsg);
    
  }
  return env;
}

CPXLPptr makeLp(CPXENVptr env, int status){
  CPXLPptr  lp = CPXcreateprob (env, &status, "lpex1");
  if ( lp == NULL ) {
    fprintf (stderr, "Failed to create LP.\n");
  }
  return lp;
}


void deleteProblem(CPXENVptr env ,CPXLPptr lp,int status){  
  if ( lp != NULL ) {
    status = CPXfreeprob (env, &lp);
    if ( status ) {
      fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status);
    }
  }
  if ( env != NULL ) {
    status = CPXcloseCPLEX (&env);
    if ( status ) {
      char errmsg[1024];
      fprintf (stderr, "Could not close CPLEX environment.\n");
      CPXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
    }
  }
}

int solveProblemMIP(CPXENVptr env ,CPXLPptr lp,int status,int* solstat, double* objval,double** x){
 status = CPXmipopt (env, lp);
  if ( status ) {
    fprintf (stderr, "Failed to optimize LP.\n");
  }
  
  status = CPXsolution (env, lp, solstat, objval, (*x), NULL, NULL, NULL);
  if ( status ) {
    fprintf (stderr, "Failed to obtain solution.\n");
    cout<<"status: "<<status<<"\n";
  }
  printf ("\nSolution solstat = %d\n", (*solstat));
  printf ("Solution value = %f\n", (*objval));
  return status;
}

int solveProblemLP(CPXENVptr env ,CPXLPptr lp,int status,int* solstat, double* objval,double** x){
 status = CPXlpopt (env, lp);
  if ( status ) {
    fprintf (stderr, "Failed to optimize LP.\n");
  }
  
  status = CPXsolution (env, lp, solstat, objval, (*x), NULL, NULL, NULL);
  if ( status ) {
    fprintf (stderr, "Failed to obtain solution.\n");
  }
  printf ("\nSolution status = %d\n", (*solstat));
  printf ("Solution value = %f\n", (*objval));
  return status;
}
